home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
mpfeel.lha
/
MPFeel
/
Modules
/
pretty.em
< prev
next >
Wrap
Lisp/Scheme
|
1992-10-06
|
11KB
|
334 lines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; EuLisp Module Copyright (C) University of Bath 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pretty printer based on the A.C.Norman Prettyprinter, and distributed
;; with Reduce, and used in Cambridge LISP
;; Translated to EuLisp by John Fitch 1991 Jan 1
;; Copyright Codemist Ltd
(defmodule pretty
(standard
trace
; loops
(rename ((cprog prog)) prog)
(except (prog) do-macs)) ()
()
(defgeneric explode-to-list (x))
(defmethod explode-to-list ((x object)) (generic-convert x '(a list)))
(defmethod explode-to-list ((x symbol)) (explode x))
(defmethod explode-to-list ((x string))
(let ((ans nil))
(dotimes i 1 (string-length x) (setq ans (cons (string-ref x i) ans)))
(nreverse ans)))
(defmethod explode-to-list ((x integer))
(if (>= x 0) (explode-int x)
(cons #\- (explode-int (- x)))))
(defun explode-int (x)
(let ((ans nil))
(if (> x 9) (setq ans (explode-int (/ x 10))) nil)
(append ans (cdr (assoc (remainder x 10)
'((0 . (#\0)) (1 . (#\1)) (2 . (#\2)) (3 . (#\3))
(4 . (#\4)) (5 . (#\5)) (6 . (#\6)) (7 . (#\7))
(8 . (#\8)) (9 . (#\9))) equal)))))
(defmethod explode-to-list ((x character))
(cond ((equal x #\space) '(#\# #\\ #\s #\p #\a #\c #\e))
((equal x #\newline) '(#\# #\\ #\n #\e #\w #\l #\i #\n #\e))
((equal x #\alert) '(#\# #\\ #\a #\l #\e #\r #\t))
((equal x #\backspace)
'(#\# #\\ #\b #\a #\c #\k #\s #\p #\a #\c #\e))
((equal x #\delete) '(#\# #\\ #\d #\e #\l #\e #\t #\e))
((equal x #\formfeed) '(#\# #\\ #\f #\o #\r #\m #\f #\e #\e #\d))
((equal x #\linefeed) '(#\# #\\ #\l #\i #\n #\e #\f #\e #\e #\d))
((equal x #\return) '(#\# #\\ #\r #\e #\t #\u #\r #\n))
((equal x #\tab) '(#\# #\\ #\t #\a #\b ))
((equal x #\vertical-tab)
'(#\# #\\ #\v #\e #\r #\t #\i #\c #\a #\l #\- #\t #\a #\b))
(t (list #\# #\\ x))))
(deflocal ppformat-table (make-table eq))
(deflocal bn nil)
(deflocal bufferi nil)
(deflocal buffero nil)
(deflocal indblanks nil)
(deflocal indentlevel nil)
(deflocal initialblanks nil)
(deflocal pendingrpars nil)
(deflocal rmar nil)
(deflocal rparcount nil)
(deflocal stack nil)
(deflocal *symmetric nil)
(deflocal thin* 5)
(defconstant *linelength* 70)
(deflocal lmar 0)
(defun superprintm (xxx leftmar)
(progn
(superprinm xxx leftmar)
(newline)
xxx))
(export superprintm)
(defun superprinm (x leftmar)
(setq lmar leftmar)
(setq bufferi (setq buffero (list nil)))
(setq initialblanks 0)
(setq rparcount 0)
(setq indblanks 0)
(setq rmar (- *linelength* 3))
(cond
((< rmar 25)
(error 0 (list (+ rmar 3)
"Linelength too short for superprinting"))))
(setq bn 0)
(setq indentlevel 0)
(cond ((>= (+ lmar 20) rmar) (setq lmar (- rmar 21))))
(prindent x (+ lmar 3))
(overflow 'none)
x)
(export superprinm)
(defun prettyprint (xxx) (superprintm xxx 0))
(export prettyprint)
(defun prindent (x n)
(cond
((atom x) (cond
((vectorp x) (prvector x n))
(t (mapc putch
(if *symmetric
(if (stringp x) (explodes x)
(explodefun x))
(explode-to-list x))))))
((quotep x) (putch #\') (prindent (cadr x) (+ n 1)))
(t (let ((cx nil))
(tagbody
(cond
((> (* 4 n) (* 3 rmar))
(overflow 'all)
(setq n (/ n 8))
(cond ((> initialblanks n)
(setq lmar (+ (- lmar initialblanks) n))
(setq initialblanks n)))))
(setq stack (cons (list n nil 0) stack))
(putch (cons 'lpar (car stack)))
(setq cx (car x))
(prindent cx (+ n 1))
(cond ((and (symbolp cx) (not (atom (cdr x))))
(setq cx (table-ref ppformat-table cx)))
(t (setq cx nil)))
(cond ((and (equal cx 2) (atom (cddr x))) (setq cx nil)))
(cond ((eq cx 'prog)
(putch #\space)
(prindent (car (setq x (cdr x))) (+ n 3))))
(setq x (cdr x))
scan (cond ((atom x) (go outt)))
(finishpending)
(cond ((eq cx 'prog)
(putblank)
(overflow bufferi)
(cond ((atom (car x))
(setq lmar (setq initialblanks
(max (- lmar 6) 0)))
(prindent (car x) (- n 3))
(setq x (cdr x))
(cond ((and (not (atom x)) (atom (car x)))
(go scan)))
(if (> (+ lmar bn) n)
(putblank)
(dotimes i (+ lmar bn) (- n 1)
(putch #\space)))
(cond ((atom x) (go outt))))))
((numberp cx)
(setq cx (- cx 1))
(cond ((equal cx 0) (setq cx nil)))
(putch #\space))
(t (putblank)))
(prindent (car x) (+ n 3))
(setq x (cdr x))
(go scan)
outt (cond ((not (null x))
(finishpending)
(putblank)
(putch #\.)
(putch #\space)
(prindent x (+ n 5))))
(putch (cons 'rpar (- n 3)))
(cond ((and
(equal (cadr (car stack)) 'indent)
(not (null (cdddr (car stack)))) )
(overflow (car (cdddr (car stack)))) )
(t (endlist (car stack))))
(setq stack (cdr stack)))))))
(defun prvector (x n)
(let ((bound nil))
(setq bound (vector-length x))
(setq stack (cons (list n nil 0) stack))
(putch (cons 'lsquare (car stack)))
(prindent (vector-ref x 0) (+ n 3))
(dotimes i 1 bound
(putch #\,)
(putblank)
(prindent (vector-ref x i) (+ n 3)))
(putch (cons 'rsquare (- n 3)))
(endlist (car stack))
(setq stack (cdr stack))))
(defun putblank ()
(putch (car stack))
((setter car) (cddr (car stack)) (+ (caddr (car stack)) 1))
((setter cdr) (cddr (car stack)) (cons bufferi (cdddr (car stack))))
(setq indblanks (+ indblanks 1)))
(defun endlist (l) (setq pendingrpars (cons l pendingrpars)))
(defun finishpending ()
(mapc (lambda (stackframe)
(cond
((not (equal (cadr stackframe) 'indent))
(mapc (lambda (b)
((setter car) b #\space)
(setq indblanks (- indblanks 1)))
(cdddr stackframe))
((setter cdr) (cddr stackframe) t)))
(car stackframe))
pendingrpars)
(setq pendingrpars nil))
(defun quotep (x)
(and (not (atom x)) (eq (car x) 'quote)
(not (atom (cdr x))) (null (cddr x))))
((setter table-ref) ppformat-table 'prog 'prog)
((setter table-ref) ppformat-table 'lambda 1)
((setter table-ref) ppformat-table 'setq 1)
((setter table-ref) ppformat-table 'set 1)
((setter table-ref) ppformat-table 'dynamic-setq 1)
((setter table-ref) ppformat-table 'while 1)
((setter table-ref) ppformat-table 't 1)
((setter table-ref) ppformat-table 'defun 2)
((setter table-ref) ppformat-table 'defmethod 2)
((setter table-ref) ppformat-table 'defgeneric 2)
((setter table-ref) ppformat-table 'defmacro 2)
((setter table-ref) ppformat-table 'deflocal 3)
((setter table-ref) ppformat-table 'defconstant 3)
((setter table-ref) ppformat-table 'let 1)
((setter table-ref) ppformat-table 'dynamic-let 1)
((setter table-ref) ppformat-table 'let* 1)
((setter table-ref) ppformat-table 'if 2)
((setter table-ref) ppformat-table 'dotimes 3)
;;((setter table-ref) ppformat-table 'mapc 4)
(defun putch (c)
(let ((nocheck nil))
(cond
((atom c) (setq rparcount 0))
((numberp (car c))
(setq rparcount 0)
(setq nocheck t))
((eq (car c) 'rpar)
(setq rparcount (+ rparcount 1))
(cond
((> rparcount 4)
(putch #\space)
(setq rparcount 2))))
(t (setq rparcount 0)))
(if nocheck nil (while (>= (+ lmar bn) rmar) (overflow 'more)))
((setter cdr) bufferi (list c))
(setq bufferi (cdr bufferi))
(setq bn (+ bn 1))))
(defun overflow (flg)
(prog (c blankstoskip)
(cond
((and
(= indblanks 0)
(> initialblanks 3)
(eq flg 'more))
(setq initialblanks (- initialblanks 3))
(setq lmar (- lmar 3))
(return 'moved-left)))
fblank(cond
((= bn 0)
(cond ((not (eq flg 'more)) (return 'empty)))
(cond ((atom (car buffero)) (prin "%+")))
(newline)
(setq lmar 0)
(return 'continued))
(t (dotimes i 1 initialblanks (prin #\space))
(setq initialblanks 0)))
(setq buffero (cdr buffero))
(setq bn (- bn 1))
(setq lmar (+ lmar 1))
(setq c (car buffero))
(cond
((atom c) (prin c) (go fblank))
((numberp (car c))
(cond
((not (atom blankstoskip))
(prin #\space)
(setq indblanks (- indblanks 1))
(cond
((eq c (car blankstoskip))
((setter cdr)
blankstoskip
(- (cdr blankstoskip) 1))
(cond
((equal (cdr blankstoskip) 0)
(setq blankstoskip t)))))
(go fblank))
(t (go blankfound))))
((or (eq (car c) 'lpar) (eq (car c) 'lsquare))
(prin (if (eq (car c) 'lpar) #\( #\[))
(cond ((eq flg 'none) (go fblank)))
(setq c (cdr c))
(cond ((not (null (cdddr c))) (go fblank)))
(cond
((> (car c) indentlevel)
(setq indentlevel (car c))
((setter car) (cdr c) 'indent)))
(go fblank))
((or (eq (car c) 'rpar) (eq (car c) 'rsquare))
(cond
((< (cdr c) indentlevel) (setq indentlevel (cdr c))))
(prin (if (eq (car c) 'rpar) #\) #\]))
(go fblank))
(t (error 0 (list c "UNKNOWN TAG IN OVERFLOW"))))
blankfound
(cond ((eqcar (cdddr c) buffero) ((setter cdr) (cddr c) nil)))
(setq indblanks (- indblanks 1))
(cond
((> (car c) indentlevel)
(cond ((eq flg 'none) (prin #\space) (go fblank)))
(cond
(blankstoskip (setq blankstoskip nil))
(t (setq indentlevel (car c))
((setter car) (cdr c) 'indent))) ))
(cond
((> (caddr c) (- thin* 1))
(setq blankstoskip (cons c (- (caddr c) 2)))
((setter car) (cdr c) 'thin)
((setter car) (cddr c) 1)
(setq indentlevel (- (car c) 1))
(prin #\space)
(go fblank)))
((setter car) (cddr c) (- (caddr c) 1))
(newline)
(setq lmar (setq initialblanks (car c)))
(cond ((eq buffero flg) (return 'to!-flg)))
(cond ((or blankstoskip (not (eq flg 'more))) (go fblank)))
(return 'more)))
)